FIT2-2023b 第06回 オブジェクト
アナウンス
リモート授業協力ありがとうございました
12/20および01/24は特に予定を開けておくこと
12/27はリモートの予定 ※中間発表予備枠を兼ねる
中間発表、最終発表を行います
https://gyazo.com/926758277f9ba9882d0d1f17e029e5ed
前回授業の復習
先週の成果物のミソ
①ボールを3個に増やす
https://gyazo.com/e0c44ebbd093e62404940fe0a33aa6d0
②ゲームオーバーを管理する
https://gyazo.com/1a6c598daa6419dedea97a633afcece8
①ボールを3個に増やす = 「リスト」の利用
code:python
# ballx, ballyそれぞれに値を3つもたせる (各列が各ボールに対応)
speed = 1
# 1個目のボールのx,y座標は以下のように取り出せる
# 1個目が0 になる点に注意 (設計として最初の要素は0番目となる) pyxel.circ(ballx0, bally0, 10, 6) # 以下のようにfor文を利用して、ballx0, ballx1, ballx2 それぞれを順番に更新可能 for i in range(0, len(ballx)):
②ゲームオーバーを管理する
code:python
# 新しい変数を2つ用意する
failed = 0
gameover = False
def update():
global ballx, bally ...(中略)... miss, gameover
# (中略)
for i in range(0, len(ballx)):
# (中略)
# ボールがキャッチできずに画面下端に来た時にmissを1増やす
miss = miss + 1
if miss >= 10:
# missが10以上になったら isGameoverをTrueに変更
gameover = True
# (中略)
def draw():
if gameover:
# ゲームオーバー時の描画
# pyxel.cls(7) を実行しないことによってゲームオーバーになった瞬間の画面を維持
pyxel.text(50, 100, 'GAME OVER', 0)
else:
# 通常のゲーム画面描画はisGameoverがTrueになると以後実行されない
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) # 中略
最終形
code:python
import pyxel
pyxel.init(200, 200)
speed = 1 # 速度の係数
score = 0 # 点数
miss = 0 # 失敗した回数を記録する変数
success = 0 # キャッチに成功した回数を記録する変数
gameover = False # ゲームオーバーかどうかを記録する変数
padx = 100
def update():
global ballx, bally, vx, vy, padx, speed, score, miss, gameover, success
if gameover:
# 処理を何もせずupdateをここで処理中断する
# ゲームオーバー後は内部処理が止まるように
return
# padの座標更新は1回で良いのでfor文の外
padx = pyxel.mouse_x
# ボールの数だけ以下処理を回す
for i in range(0, len(ballx)):
# ボールのy座標が195 (padの上端)より下にいる
# なおかつ、ボールのx座標がpadの左端(padx-20)と右端(padx+20)の間にある場合に
if ballyi >= 195 and padx - 20 <= ballxi <= padx + 20: # 点数を100増やす
score = score + 100
success = success + 1
if success >= 10:
# ボールを増やす
ballx.append(pyxel.rndi(0, 199))
bally.append(0)
angle.append(pyxel.rndi(30, 150))
vx.append(pyxel.cos(angle-1)) # -1は最後から1番目の要素を指す vy.append(pyxel.sin(angle-1)) # スピードをもとに戻す
speed = 1
# successも0に戻す
success = 0
# 接触後、ボールを上に戻してあげないと、そのまま進み続けて連続ヒットしてしまう
ballxi = pyxel.rndi(0, 199) speed = speed + 0.5 # スピードを少し早くする
if ballyi >= 200: # ボールが下端まで来たら # 失敗カウントを増やす
miss = miss + 1
if miss >= 10:
gameover = True
ballxi = pyxel.rndi(0, 199) speed = speed + 0.5 # スピードを少し早くする
if ballxi >= 200: # ボールが右端まで来たら if ballxi <= 0: # ボールが左端まで来たら def draw():
global ballx, bally, vx, vy, padx, score, miss, gameover, success
if gameover:# ゲームオーバーだったら…
# pyxel.cls(7) をあえて実行しないことで、前回処理時の画面をそのまま表示する
pyxel.text(50, 100, "GAME OVER", 0)
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) pyxel.rect(padx-20, 195, 40, 5, 14)
pyxel.text(0, 0, str(score), 0)
pyxel.run(update, draw)
本日の講義
https://gyazo.com/d8961914c1c72c0eb41eb0f9ceaa9c2a
リストの可読性の悪さを解決するための手段を伝えます
左がbefore、右がafter 上からなんとなく読んでみましょう
https://gyazo.com/0b7bbffb6670bc646c2fda8ee88f26ec
Ballという概念はどのようなものかを定義 (class Ball)
Ballという概念はどのような処理を持つかを定義 (def move)
Ballという概念に共通する値は class Ball直下に記載 (Ball.speed)
個別のBallが持つ固有の値は self.XXX で管理 (self.x, self.y)
for文がわかりやすくなっている点にも要注目
ミニプロの配点としては4点分
プログラミングを今後やっていきたなら必須で理解が求められる概念です
理解せずとも単位は取得可能です (それだけ最後のハードルではある)
余談
オブジェクト/メソッドがわかるとこんなに便利!
例えばシューティングゲームを作るとして…
code:python
class Enemy:
size = 3
color = 2
def __init__(self, x, y, vx, vy):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.hp = 100
def move(self):
self.x = self.x + self.vx
self.y = self.y + self.vy
def isDead(self):
return self.hp <= 0
def draw(self):
pyxel.rect(self.x, self.y, Enemy.size, Enemy.size, Enemy.color)
演習
Part1 B-12-2まで!
課題
B-11系統一式
必須は★★★まで (=今週は全部!)
企画書の提出も11/14期日です!